#include "precompiled.h"
#include "restoration.h"
using namespace std;
using namespace weo::engine::item;
using namespace weo::engine::character::shaman;

Restoration::Restoration()
{
    Healer::Init();
    m_Classnr = weo::engine::character::Character::isAllowed("Shaman");
    m_Basevalues.push_back(Attribute("Agility",59));
    m_Basevalues.push_back(Attribute("Intellect",103));
    m_Basevalues.push_back(Attribute("Strength",107));
    m_Basevalues.push_back(Attribute("Stamina",116));
    m_Basevalues.push_back(Attribute("Spirit",122));
    m_Basevalues.push_back(Attribute("CritSpellRating",2.2f*CritSpellRating));
    m_Basevalues.push_back(Attribute("CritSpellRating",5.0f*CritSpellRating));
    m_Basevalues.push_back(Attribute("Health",2979)); // health
    m_Basevalues.push_back(Attribute("Mana",2678)); // mana
    m_Equip.Mode(0);
    BOOST_FOREACH(Attribute attr, m_Basevalues)
    {
        handleAttribute(attr);
    }
    // base settings finished
    Buff *wshield = new Buff("Watershield");
    wshield->addAttribute(Attribute("MP5", (203*3)/60.0f * 5.0f));
    m_Buffs[wshield->Name()] = *wshield;
    m_Buffs["Manatide"].Active(true);
}
float Restoration::evaluateTF()
{
    float runtime = 600;
    float time = runtime;
    float HW8 = 61.0f/70.0f;
    float HW8cost = 440;
    float HW8heal = 1092;
    float spellcrit = m_Equip[12] / CritSpellRating;
    float manaregic = m_Equip[21];
    float haste = m_Equip[13] / HasteSpellRating;
    float spelltime = 2.5f/(1+haste/100.0f);
    float manaregooc = m_Equip[21] + 5 * 0.00932715221261f * std::sqrt(m_Equip[2]) * m_Equip[5];
    float HW8mana = HW8cost * 0.95f - (manaregic / 5.0f)*spelltime;
    float count = floor(m_Equip[35] / HW8mana);
    float castuseratio = ((manaregooc /5.0f) * spelltime) / HW8mana;
    time -= count * spelltime + max<float>(5 * castuseratio, 5);
    time = max<float>(time, 0);
    if(m_Equip.hasSpecial(1182315))
    {		
        HW8heal += 88;
    }
    float regtime = 0;
    if (time > 0)
    {
        regtime = time / (castuseratio + 1);
        regtime = min<float>(regtime, 0.3f * runtime);
        time -= regtime;
    }
    count += floor(((regtime / 5.0f) * manaregooc) / HW8mana);
    count = min<float>(count, (runtime - regtime) / spelltime);
    float HealHW8 = 1.1f * 1.18f * count * (HW8heal + m_Equip[20] * HW8 * (6.0f / 7.0f)); // no healcrits
    return m_CondFactor * HealHW8 / runtime;
}
void Restoration::filterEquip(std::vector<std::vector<const weo::engine::item::Item*>>& items)
{
    for(unsigned int i = 0;i<10;i++)
    {
        int subtype = 3;
        if(i == 1 || i == 3)
        {
            vector<const Item*> temp = m_Database->getPtrbyType(1,i+1);
            items.push_back(temp);
        }
        else
        {
            vector<const Item*> temp = m_Database->getPtrbyType(1,i+1,3); // mail		
            items.push_back(temp);
        }
    }
    items.push_back(m_Database->getPtrbyType(2,0));
    items.push_back(m_Database->getPtrbyType(2,0));
    items.push_back(m_Database->getPtrbyType(3,0));
    items.push_back(m_Database->getPtrbyType(3,0));
    // main hand weapons
    vector<const Item*> mainhand;
    for(int j = 1;j<3;j++)
    {
        vector<const Item*> weapon = m_Database->getPtrbyType(4,j,2);
        vector<const Item*>::iterator it;
        for(it=weapon.begin();it!=weapon.end();it++)
        {
            mainhand.push_back(*it);
        }
    }
    for(int j = 1;j<3;j++)
    {
        vector<const Item*> weapon = m_Database->getPtrbyType(4,j,5);
        vector<const Item*>::iterator it;
        for(it=weapon.begin();it!=weapon.end();it++)
        {
            mainhand.push_back(*it);
        }
    }
    // staff
    vector<const Item*> staff = m_Database->getPtrbyType(4,4,6);
    vector<const Item*>::iterator it;
    for(it=staff.begin();it!=staff.end();it++)
    {
        mainhand.push_back(*it);
    }
    // off hand weapons
    vector<const Item*> offhand;
    vector<const Item*> shield = m_Database->getPtrbyType(1,11);
    vector<const Item*> ohand = m_Database->getPtrbyType(1,12);
    for(it=shield.begin();it!=shield.end();it++)
    {
        offhand.push_back(*it);
    }
    for(it=ohand.begin();it!=ohand.end();it++)
    {
        offhand.push_back(*it);
    }
    items.push_back(mainhand);
    items.push_back(offhand);
    items.push_back(m_Database->getPtrbyType(4,5,15)); // totems
    items.push_back(m_Database->getPtrbyType(5,0));
    Healer::filterEquip(items);
}
void Restoration::handleAttribute(const Attribute& attr)
{
    switch(attr.Type())
    {
    case 2:
        handleAttribute(Attribute(20,attr.Value() * (m_HasBok ? 1.1f : 1.0f) * 0.3f));
        Healer::handleAttribute(attr);
        break;		
    default:
        Healer::handleAttribute(attr);
        break;
    }
}
